﻿#pragma once

#include <condition_variable>
#include <memory>
#include <mutex>
#include <queue>
#include <vector>

#include "asycipc/transport.hpp"

namespace asycipc {

class InMemoryPipeHandle : public PipeHandle {
 public:
  InMemoryPipeHandle(std::shared_ptr<std::queue<std::vector<uint8_t>>> inbox,
                     std::shared_ptr<std::queue<std::vector<uint8_t>>> outbox,
                     std::shared_ptr<std::mutex> mutex,
                     std::shared_ptr<std::condition_variable> cv);

  void Write(const std::vector<uint8_t>& data) override;
  std::vector<uint8_t> Read() override;

 private:
  std::shared_ptr<std::queue<std::vector<uint8_t>>> inbox_;
  std::shared_ptr<std::queue<std::vector<uint8_t>>> outbox_;
  std::shared_ptr<std::mutex> mutex_;
  std::shared_ptr<std::condition_variable> cv_;
};

class InMemoryPipePair {
 public:
  InMemoryPipePair();
  PipeHandlePtr ServerHandle();
  PipeHandlePtr ClientHandle();

 private:
  std::shared_ptr<std::queue<std::vector<uint8_t>>> a_to_b_;
  std::shared_ptr<std::queue<std::vector<uint8_t>>> b_to_a_;
  std::shared_ptr<std::mutex> mutex_;
  std::shared_ptr<std::condition_variable> cv_;
};

}  // namespace asycipc
